/*     */ package com.zimbra.cs.mailbox.calendar;
/*     */ 
/*     */ import com.zimbra.common.calendar.ICalTimeZone;
/*     */ import com.zimbra.common.calendar.ParsedDateTime;
/*     */ import com.zimbra.common.calendar.ParsedDuration;
/*     */ import com.zimbra.common.calendar.TimeZoneMap;
/*     */ import com.zimbra.common.calendar.ZCalendar.ICalTok;
/*     */ import com.zimbra.common.calendar.ZCalendar.ZComponent;
/*     */ import com.zimbra.common.calendar.ZCalendar.ZParameter;
/*     */ import com.zimbra.common.calendar.ZCalendar.ZProperty;
/*     */ import com.zimbra.common.localconfig.DebugConfig;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.cs.mailbox.Metadata;
/*     */ import java.text.ParseException;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Iterator;
/*     */ import java.util.List;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class RdateExdate
/*     */   implements Cloneable
/*     */ {
/*     */   private ZCalendar.ICalTok mPropertyName;
/*     */   private ZCalendar.ICalTok mValueType;
/*     */   private ICalTimeZone mTimeZone;
/*     */   private List<Object> mValues;
/*     */   private boolean mIsRdate;
/*     */   private static final String FN_IS_RDATE = "isrd";
/*     */   private static final String FN_TZID = "tzid";
/*     */   private static final String FN_VALUE_TYPE = "vt";
/*     */   private static final String FN_NUM_VALUES = "numV";
/*     */   private static final String FN_VALUE = "v";
/*     */   private static final String VT_DATE_TIME = "dt";
/*     */   private static final String VT_DATE = "d";
/*     */   private static final String VT_PERIOD = "p";
/*     */   
/*     */   public RdateExdate(ZCalendar.ICalTok propName, ICalTimeZone tz)
/*     */     throws ServiceException
/*     */   {
/*  48 */     this(propName, ZCalendar.ICalTok.DATE_TIME, tz);
/*     */   }
/*     */   
/*     */   RdateExdate(ZCalendar.ICalTok propName, ZCalendar.ICalTok valueType, ICalTimeZone tz) throws ServiceException
/*     */   {
/*  53 */     if (ZCalendar.ICalTok.RDATE.equals(propName)) {
/*  54 */       this.mIsRdate = true;
/*  55 */     } else if (!ZCalendar.ICalTok.EXDATE.equals(propName)) {
/*  56 */       throw ServiceException.INVALID_REQUEST("Property " + propName.toString() + " is neither a RDATE nor an EXDATE", null);
/*     */     }
/*  58 */     this.mPropertyName = propName;
/*     */     
/*  60 */     this.mTimeZone = tz;
/*  61 */     setValueType(valueType);
/*  62 */     this.mValues = new ArrayList();
/*     */   }
/*     */   
/*     */   public Object clone() {
/*  66 */     RdateExdate copy = null;
/*     */     try {
/*  68 */       copy = new RdateExdate(this.mPropertyName, this.mValueType, this.mTimeZone);
/*     */     }
/*     */     catch (ServiceException e) {}
/*     */     
/*  72 */     for (Object val : this.mValues) {
/*  73 */       if ((val instanceof ParsedDateTime)) {
/*  74 */         copy.addValue((ParsedDateTime)((ParsedDateTime)val).clone());
/*  75 */       } else if ((val instanceof ParsedDuration))
/*  76 */         copy.addValue((ParsedDuration)((ParsedDuration)val).clone());
/*     */     }
/*  78 */     return copy;
/*     */   }
/*     */   
/*     */   public void setValueType(ZCalendar.ICalTok valueType) throws ServiceException {
/*  82 */     switch (valueType) {
/*     */     case DATE_TIME: 
/*     */     case DATE: 
/*     */       break;
/*     */     case PERIOD: 
/*  87 */       if (!this.mIsRdate) {
/*  88 */         throw ServiceException.INVALID_REQUEST("PERIOD value type not allowed in EXDATE", null);
/*     */       }
/*     */       break;
/*     */     default: 
/*  92 */       throw ServiceException.INVALID_REQUEST("Invalid value type " + valueType.toString() + " in " + this.mPropertyName.toString(), null);
/*     */     }
/*     */     
/*     */     
/*  96 */     this.mValueType = valueType;
/*     */   }
/*     */   
/*     */   public void addValue(Object value) {
/* 100 */     this.mValues.add(value);
/*     */   }
/*     */   
/* 103 */   public int numValues() { return this.mValues.size(); }
/* 104 */   public Iterator<Object> valueIterator() { return this.mValues.iterator(); }
/*     */   
/* 106 */   public boolean isRDATE() { return this.mIsRdate; }
/* 107 */   public boolean isEXDATE() { return !this.mIsRdate; }
/*     */   
/* 109 */   public ICalTimeZone getTimeZone() { return this.mTimeZone; }
/*     */   
/*     */   public String toString() {
/* 112 */     StringBuilder sb = new StringBuilder(this.mPropertyName.toString());
/* 113 */     if (!ZCalendar.ICalTok.DATE_TIME.equals(this.mValueType))
/* 114 */       sb.append(";VALUE=").append(this.mValueType.toString());
/* 115 */     if (this.mTimeZone != null)
/* 116 */       sb.append(";TZID=").append(this.mTimeZone.getID());
/* 117 */     sb.append(":");
/* 118 */     sb.append(getDatesCSV());
/* 119 */     return sb.toString();
/*     */   }
/*     */   
/*     */   private String getDatesCSV() {
/* 123 */     StringBuilder sb = new StringBuilder();
/* 124 */     boolean first = true;
/* 125 */     for (Object value : this.mValues) {
/* 126 */       if (first) {
/* 127 */         first = false;
/*     */       } else
/* 129 */         sb.append(",");
/* 130 */       if ((value instanceof ParsedDateTime)) {
/* 131 */         ParsedDateTime t = (ParsedDateTime)value;
/* 132 */         sb.append(t.getDateTimePartString(false));
/* 133 */       } else if ((value instanceof Period)) {
/* 134 */         sb.append(value.toString());
/*     */       } }
/* 136 */     return sb.toString();
/*     */   }
/*     */   
/*     */   public Element toXml(Element parent) {
/* 140 */     if ((isRDATE()) && (!DebugConfig.enableRdate)) {
/* 141 */       return null;
/*     */     }
/* 143 */     Element dateElem = parent.addElement("dates");
/* 144 */     if (this.mTimeZone != null)
/* 145 */       dateElem.addAttribute("tz", this.mTimeZone.getID());
/* 146 */     for (Object val : this.mValues) {
/* 147 */       Element dtvalElem = dateElem.addElement("dtval");
/* 148 */       if ((val instanceof ParsedDateTime)) {
/* 149 */         ParsedDateTime dt = (ParsedDateTime)val;
/* 150 */         Element startElem = dtvalElem.addElement("s");
/* 151 */         startElem.addAttribute("d", dt.getDateTimePartString(false));
/*     */       }
/* 153 */       else if ((val instanceof Period)) {
/* 154 */         Period p = (Period)val;
/* 155 */         Element startElem = dtvalElem.addElement("s");
/* 156 */         startElem.addAttribute("d", p.getStart().getDateTimePartString(false));
/*     */         
/* 158 */         if (p.hasEnd()) {
/* 159 */           Element endElem = dtvalElem.addElement("e");
/* 160 */           endElem.addAttribute("d", p.getEnd().getDateTimePartString(false));
/*     */         }
/*     */         else {
/* 163 */           p.getDuration().toXml(dtvalElem);
/*     */         }
/*     */       }
/*     */     }
/* 167 */     return dateElem;
/*     */   }
/*     */   
/*     */   public static RdateExdate parse(ZCalendar.ZProperty prop, TimeZoneMap tzmap) throws ServiceException
/*     */   {
/* 172 */     ZCalendar.ICalTok propName = prop.getToken();
/*     */     
/* 174 */     ZCalendar.ZParameter valueParam = prop.getParameter(ZCalendar.ICalTok.VALUE);
/* 175 */     ZCalendar.ICalTok valueType = ZCalendar.ICalTok.DATE_TIME;
/* 176 */     if (valueParam != null) {
/* 177 */       String typeStr = valueParam.getValue();
/* 178 */       if (typeStr != null) {
/* 179 */         valueType = ZCalendar.ICalTok.lookup(typeStr);
/* 180 */         if (valueType == null) {
/* 181 */           throw ServiceException.INVALID_REQUEST("Invalid " + propName.toString() + " value type " + typeStr, null);
/*     */         }
/*     */       }
/*     */     }
/*     */     
/*     */ 
/* 187 */     String tzid = prop.getParameterVal(ZCalendar.ICalTok.TZID, null);
/* 188 */     ICalTimeZone tz = null;
/* 189 */     if (tzid != null) {
/* 190 */       tz = tzmap.lookupAndAdd(tzid);
/*     */     }
/* 192 */     RdateExdate rexdate = new RdateExdate(propName, valueType, tz);
/*     */     
/* 194 */     String csv = prop.getValue();
/* 195 */     if ((csv == null) || (csv.length() == 0)) {
/* 196 */       throw ServiceException.INVALID_REQUEST("Empty value not allowed for " + propName.toString() + " property", null);
/*     */     }
/*     */     
/* 199 */     for (String value : csv.split(",")) {
/*     */       try {
/* 201 */         switch (valueType) {
/*     */         case DATE_TIME: 
/*     */         case DATE: 
/* 204 */           ParsedDateTime dt = ParsedDateTime.parse(value, tzmap, tz, tzmap.getLocalTimeZone());
/* 205 */           rexdate.addValue(dt);
/* 206 */           break;
/*     */         case PERIOD: 
/* 208 */           Period p = Period.parse(value, tz, tzmap);
/* 209 */           rexdate.addValue(p);
/*     */         }
/*     */       }
/*     */       catch (ParseException e) {
/* 213 */         throw ServiceException.INVALID_REQUEST("Unable to parse " + propName.toString() + " value \"" + value + "\"", e);
/*     */       }
/*     */     }
/*     */     
/*     */ 
/*     */ 
/* 219 */     return rexdate;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public Metadata encodeMetadata()
/*     */   {
/* 233 */     Metadata meta = new Metadata();
/*     */     
/* 235 */     meta.put("isrd", isRDATE());
/*     */     
/* 237 */     if (this.mTimeZone != null) {
/* 238 */       meta.put("tzid", this.mTimeZone.getID());
/*     */     }
/* 240 */     String vt = "dt";
/* 241 */     if (!ZCalendar.ICalTok.DATE_TIME.equals(this.mValueType)) {
/* 242 */       vt = ZCalendar.ICalTok.DATE.equals(this.mValueType) ? "d" : "p";
/*     */     }
/* 244 */     meta.put("vt", vt);
/*     */     
/* 246 */     meta.put("numV", this.mValues.size());
/* 247 */     int i = 0;
/* 248 */     for (Object val : this.mValues) {
/* 249 */       if ((val instanceof ParsedDateTime)) {
/* 250 */         ParsedDateTime dt = (ParsedDateTime)val;
/* 251 */         meta.put("v" + i, dt.getDateTimePartString(false));
/* 252 */       } else if ((val instanceof Period)) {
/* 253 */         Period p = (Period)val;
/* 254 */         meta.put("v" + i, p.encodeMetadata());
/*     */       }
/* 256 */       i++;
/*     */     }
/*     */     
/* 259 */     return meta;
/*     */   }
/*     */   
/*     */   public static RdateExdate decodeMetadata(Metadata meta, TimeZoneMap tzmap) throws ServiceException
/*     */   {
/* 264 */     boolean isRdate = meta.getBool("isrd", true);
/* 265 */     ZCalendar.ICalTok propName = isRdate ? ZCalendar.ICalTok.RDATE : ZCalendar.ICalTok.EXDATE;
/*     */     
/* 267 */     ICalTimeZone tz = null;
/* 268 */     String tzid = meta.get("tzid", null);
/* 269 */     if (tzid != null) {
/* 270 */       tz = tzmap.lookupAndAdd(tzid);
/*     */     }
/* 272 */     String vt = meta.get("vt", "dt");
/*     */     ZCalendar.ICalTok valueType;
/* 274 */     ZCalendar.ICalTok valueType; if (vt.equals("dt")) {
/* 275 */       valueType = ZCalendar.ICalTok.DATE_TIME; } else { ZCalendar.ICalTok valueType;
/* 276 */       if (vt.equals("d")) {
/* 277 */         valueType = ZCalendar.ICalTok.DATE;
/*     */       } else
/* 279 */         valueType = ZCalendar.ICalTok.PERIOD;
/*     */     }
/* 281 */     RdateExdate rexdate = new RdateExdate(propName, valueType, tz);
/*     */     
/* 283 */     int numValues = (int)meta.getLong("numV", 0L);
/* 284 */     for (int i = 0; i < numValues; i++) {
/* 285 */       String key = "v" + i;
/* 286 */       if ((valueType.equals(ZCalendar.ICalTok.DATE_TIME)) || (valueType.equals(ZCalendar.ICalTok.DATE))) {
/* 287 */         String dtStr = meta.get(key);
/*     */         ParsedDateTime dt;
/*     */         try {
/* 290 */           dt = ParsedDateTime.parse(dtStr, tzmap, tz, tzmap.getLocalTimeZone());
/*     */         } catch (ParseException e) {
/* 292 */           throw ServiceException.INVALID_REQUEST("Invalid " + propName.toString() + " date/time in metadata: " + meta.toString(), e);
/*     */         }
/*     */         
/*     */ 
/* 296 */         rexdate.addValue(dt);
/* 297 */       } else if (valueType.equals(ZCalendar.ICalTok.PERIOD)) {
/* 298 */         Period p = Period.decodeMetadata(meta.getMap(key), tz, tzmap);
/* 299 */         rexdate.addValue(p);
/*     */       }
/*     */     }
/*     */     
/* 303 */     return rexdate;
/*     */   }
/*     */   
/*     */ 
/*     */   void addAsSeparateProperties(ZCalendar.ZComponent comp)
/*     */   {
/* 309 */     if ((isRDATE()) && (!DebugConfig.enableRdate)) {
/* 310 */       return;
/*     */     }
/* 312 */     ZCalendar.ZParameter tzid = this.mTimeZone != null ? new ZCalendar.ZParameter(ZCalendar.ICalTok.TZID, this.mTimeZone.getID()) : null;
/* 313 */     ZCalendar.ZParameter valType = !ZCalendar.ICalTok.DATE_TIME.equals(this.mValueType) ? new ZCalendar.ZParameter(ZCalendar.ICalTok.VALUE, this.mValueType.toString()) : null;
/* 314 */     for (Object value : this.mValues) {
/* 315 */       ZCalendar.ZProperty prop = new ZCalendar.ZProperty(this.mPropertyName);
/* 316 */       if (tzid != null) {
/* 317 */         prop.addParameter(tzid);
/*     */       }
/* 319 */       if (valType != null) {
/* 320 */         prop.addParameter(valType);
/*     */       }
/* 322 */       if ((value instanceof ParsedDateTime)) {
/* 323 */         ParsedDateTime t = (ParsedDateTime)value;
/* 324 */         prop.setValue(t.getDateTimePartString(false));
/* 325 */       } else if ((value instanceof Period)) {
/* 326 */         prop.setValue(value.toString());
/*     */       }
/* 328 */       comp.addProperty(prop);
/*     */     }
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/mailbox/calendar/RdateExdate.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */